/* 
 * 
 * Copyright 2011 The University of Adelaide
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 *  
 */

package au.org.aekos.ands.global.parse;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import au.org.aekos.ands.global.Schema.EntityType;

import com.google.common.base.Splitter;

/**
 * Provides a framework for parsing metadata specified in a {@link Properties} file.
 *
 * @param <T> the field which is to be retrieved from the properties.
 */
public abstract class PropertyParser<T> {
	protected Properties properties;

	protected Class<T> t;
	private T[] emptyT;
	
	/**
	 * Instantiates a new property parser.
	 *
	 * @param t the metadata field.
	 * @param properties the properties from which metadata will be read.
	 */
	@SuppressWarnings("unchecked")
	protected PropertyParser(Class<T> t, Properties properties) {
		this.t = t;
		this.properties = properties;
		
		emptyT = (T[])Array.newInstance(t, 0);
	}

    /**
     * Shortcut for retrieving a property of the given name.
     *
     * @param key the key.
     * @return the property value, if present, else null.
     */
    protected String prop(String key) { return properties.getProperty(key); }
	
	/**
	 * Parses the properties for all objects of the given entity type.
	 *
	 * @param type the entity type.
	 * @return the list of properties.
	 */
	public abstract List<T> parse(EntityType type);
	
	/**
	 * Parses the properties for the entity of the given name and type.
	 *
	 * @param type the entity type.
	 * @param identifier the entity identifier.
	 * @return the list of properties.
	 */
	public abstract List<T> parse(EntityType type, String identifier);
	
	/**
	 * Parses the properties for the entity of the given name and type.
	 *
	 * @param type the entity type.
	 * @param identifier the entity identifier.
	 * @return the array of properties.
	 */
	public T[] getMetadata(EntityType type, String identifier) {
		List<T> list = parse(type, identifier);
		list.addAll(parse(type));
		return list.toArray(emptyT);
	}
	
	private Splitter splitter = Splitter.on(".").trimResults().omitEmptyStrings();
	
	/**
	 * Convenience method for splitting dot-separated property keys.
	 * 
	 * @param key the property key to split.
	 * @return the components of the property key.
	 */
	protected List<String> split(String key) {
		List<String> list = new ArrayList<String>();
		for (String token : splitter.split(key)) {
			list.add(token);
		}
		return list;
	}
}
